import { _decorator, Component, Node, Camera, CCInteger, game, director, CCBoolean, v3, Vec3, tween, math, Tween } from 'cc';
import { EventDispatcher } from '../../ngame/util/EventDispatcher';
import { ICameraController } from '../controller/ICameraController';
import GameConst from '../GameConst';
import { ProjectionTool } from './tools/ProjectionTool';
const { ccclass, property,executeInEditMode } = _decorator;

/**
 * 全局视角管理系统
 */

@ccclass('PerspectiveManage')
@executeInEditMode(true)
export class ProjectionManage extends Component {

    //相机
    @property({ type:Camera, displayName:"相机"})
    camera:Camera = null;
    iCameraController:ICameraController = null;

    //相机锚点
    @property({ type:Node, displayName:"相机锚点"})
    cameraPos:Node = null;

    //x角度
    @property({ type:CCInteger, displayName:"x默认角度"})
    xDefaultAngle:number = -55;

    //相机最高高度
    @property({ type:CCInteger, displayName:"相机最高高度"})
    cameraMaxH:number = 20;

    //相机正常高度
    @property({ type:CCInteger, displayName:"相机正常高度"})
    cameraDefaultH:number = 5;

    //x角度(生效)
    _xAngle:number = 0;
    get xAngle(){ return this._xAngle }
    set xAngle(value){ 
        this.updateXAngle(this._xAngle = value);
    }

    //高度
    _height:number = 5;
    @property({ type:CCInteger, displayName:"高度"})
    get height(){return this._height}
    set height(value){this._height = value;this.camera.node.position = v3(0,0,value)}

    // //跟随的玩家
    // @property({ type:Node, displayName:"跟随的玩家"})
    // follow:Node = null;
    //视角集合
    projections:ProjectionTool[] = [];

    //当前视角高度
    _hcamera:number = 0;
    set hcamera(value){
        this._hcamera = value;
        this.updateHCamera(this._hcamera);
    }
    get hcamera(){
        return this._hcamera;
    }
    
    _apply:boolean = false;
    //动态生效
    @property({ type:CCBoolean, displayName:"动态生效"})
    set apply(value){ this.init();this._apply = value;}
    get apply(){ return this._apply;}



    onLoad() {

        this._hcamera = this.camera.node.position.z;

        this.iCameraController = this.camera.node.parent.getComponent(ICameraController);

        this.init();
        this.onEvent();
        
    }

    onDestroy(){

        this.offEvent();
        
    }

    onEvent(){
        
        //绑定鼠标滚轮地图事件
        EventDispatcher.getIns().on(GameConst.TOUCH.TOUCH_WORLD_WHEEL,this.wheelWorld,this);

    }

    offEvent(){
        
        
        EventDispatcher.getIns().off(GameConst.TOUCH.TOUCH_WORLD_WHEEL,this.wheelWorld);

    }

    
    //绑定鼠标滚轮地图事件
    wheelWorld(event){
        this.hcamera = this.hcamera+=(-(event.getScrollY()) / 500);
    }

    //生效相机高度
    updateHCamera(hcamera = this.hcamera){

        this._hcamera = hcamera = Math.max(Math.min(hcamera,this.cameraMaxH),this.cameraDefaultH);

        let t = 0.2;
        let that = this;

        //是否进行长时间过度
        if(Math.abs(this.camera.node.position.z - this.hcamera) > 5)
            t += Math.abs(this.camera.node.position.z - this.hcamera) * 0.01;

        tween(this.camera.node.position)
            .to(
                t,
                v3(0,0,hcamera),
                {
                    onUpdate(target:Vec3, ratio:number){
                        that.camera.node.position = target;

                        if(that.camera.node.position.z > that.cameraMaxH/2){
                            that.iCameraController.isCenter = true;
                            let h = target.z - ( that.cameraMaxH/2);
                            that.xAngle = math.lerp(that.xDefaultAngle,-90,Math.min(h / (that.cameraMaxH/2),1));
                        }else{
                            that.iCameraController.isCenter = false;
                        }
                    }
                }
            ).start();

    }

    //生效角度
    updateXAngle(xAngle = this.xAngle){

        this.projections.forEach((tool) => {
            tool.node.eulerAngles = v3(xAngle,0,0);
        });

        //初始化相机
        this.cameraPos.eulerAngles = v3(xAngle,0,0);

    }

    init(){

        //获取所有视角工具
        this.projections = director.getScene().getComponentsInChildren(ProjectionTool);
        this._xAngle = this.xDefaultAngle;

        this.camera.node.eulerAngles = v3(0,0,0);
        this.camera.node.position = v3(0,0,this.height);

    }

}

